package com.spring.framework.config.value;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 注解@Value可以获取其他bean的属性值然后注入到自己的属性中，这实际上也是SPEL的作用，但是这要求尝试获取属性的bean的属性提供相应的
 * getter方法或者属性是public修饰的。对于集合类型，也可以注入集合的索引元素或者map的key的value。
 *
 * @author xuweizhi
 * @since 2020/12/15 15:36
 */
@Component
@SuppressWarnings("all")
public class ValueOtherBean {

	//SPEL获取其他bean的属性值
	/**
	 * 字面量
	 */
	@Value("#{valueOtherBeanA.property1}")
	private String valueOtherBeanAproperty1;
	@Value("#{valueOtherBeanA.property2}")
	private double valueOtherBeanAproperty2;

	/**
	 * 数组/集合
	 */
	@Value("#{valueOtherBeanA.property3}")
	private String[] valueOtherBeanAproperty3;

	@Value("#{valueOtherBeanA.property4}")
	private String[] valueOtherBeanAproperty4;

	@Value("#{valueOtherBeanA.property5}")
	private Map<String, Integer> valueOtherBeanAproperty5;

	/**
	 * 数组/集合某个索引/key的数据
	 */
	@Value("#{valueOtherBeanA.property3[0]}")
	private String valueOtherBeanAproperty3One;
	@Value("#{valueOtherBeanA.property4[1]}")
	private String[] valueOtherBeanAproperty4One;

	@Value("#{valueOtherBeanA.property5[key2]}")
	private Integer valueOtherBeanAproperty5Key3;


	/**
	 * 其他bean
	 * 想要使用其他bean的属性，要求其他bean提供属性的getter方法或者属性必须是public修饰的
	 */
	@Component("valueOtherBeanA")
	public static class ValueOtherBeanA {
		/**
		 * 一个字符串
		 */
		@Value("property1")
		private String property1;
		/**
		 * SPEL取一个随机数
		 */
		@Value("#{ T(java.lang.Math).random() * 100.0}")
		private double property2;

		@Value("#{'property1,property2,property3'.split(',')}")
		private String[] property3;

		@Value("#{'property1,property2,property3'.split(',')}")
		public List<String> property4;

		@Value("#{{key1: '1', key2: '2'}}")
		public Map<String, Integer> property5;

		public String getProperty1() {
			return property1;
		}

		public double getProperty2() {
			return property2;
		}

		public String[] getProperty3() {
			return property3;
		}
	}

	@Override
	public String toString() {
		return "ValueOtherBean{" +
				"valueOtherBeanAproperty1='" + valueOtherBeanAproperty1 + '\'' +
				", valueOtherBeanAproperty2=" + valueOtherBeanAproperty2 +
				", valueOtherBeanAproperty3=" + Arrays.toString(valueOtherBeanAproperty3) +
				", valueOtherBeanAproperty4=" + Arrays.toString(valueOtherBeanAproperty4) +
				", valueOtherBeanAproperty5=" + valueOtherBeanAproperty5 +
				", valueOtherBeanAproperty3One='" + valueOtherBeanAproperty3One + '\'' +
				", valueOtherBeanAproperty4One=" + Arrays.toString(valueOtherBeanAproperty4One) +
				", valueOtherBeanAproperty5Key3=" + valueOtherBeanAproperty5Key3 +
				'}';
	}

	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ValueOtherBean.class);
		System.out.println(applicationContext.getBean(ValueOtherBean.class));
	}
}
